pseudoPODs
Smart Class Members That Masquerade as POD Members
All the preceding remarks apply to the macro version of pseudoPODs. The template version is less efficient and requires more typing, so should be used only by those that really, really hate macros.
Each pseudoPOD requires 1 pointer in the macro version, versus 3 pointers for the template version, so the memory consumption is higher. Arrays made from templates are a little worse, requiring 3 pointers plus 1 integer per array element, versus 1 pointer per array element for arrays made from macros.
As for coding labor, the macro approach requires 1 additional line per pseudoPOD, while the template approach requires 4 for an individual pseudoPOD, and 8 for an array. Macros could reduce the typing required, but that would violate the assumption that the template approach will only be used by those that dislike macros.
Finally, the data within the pseudoPOD's code, including the pointers, is not private - the class has to initialize it, but C++ no longer permits befriending a class through a template argument, so I had to make the data within the pseudoPOD code public, exposing it to accidental corruption by code outside the class.
Integer pseudoPODs Using Templates:
ppodt_i <fred_c, int> name; // create
// the pseudoPOD
private: int name_value; public:
// place in constructor() of class fred_c
name.ep=this;
name.ep_get = &fred_c::get_name;
name.ep_set = &fred_c::set_name;
// the get_name() & set_name(int in) functions
// are identical to those used
// for pseudoPODs made by macros.
Other Non-Pointer Non-Array Types of pseudoPODs Using Templates:
same as for integer, but for "int" substitute one of "long", "unsigned int", "unsigned long", "short", "unsigned short", "char", "unsigned char", "bool", "float", "double" or "long double".
In addition, for "float", "double", & "long double" change the template name from ppodt_i to ppodt_f.
Integer Pointer pseudoPODs Using Templates:
ppodt_p <fred_c, int*> name; // create
// the pseudoPOD
private: int *name_value; public:
// place in constructor() of class fred_c
name.ep=this;
name.ep_get = &fred_c::get_name;
name.ep_set = &fred_c::set_name;
// the *get_name() & *set_name(int *in) functions
// are identical to those used for
// pseudoPODs made by macros.
Other Pointer pseudoPODs Using Templates:
same as for integer, but for "int*" substitute one of "unsigned int*", "unsigned long*", "short*", "unsigned short*", "char*", "unsigned char*", "bool*", "float*", "double*" or "long double*".
In addition, for "float", "double", & "long double" change the template name from ppodt_p_i to ppodt_p_f.
Arrays of Integer pseudoPODs Using Templates:
const static int name_array_len = 50; // create
// the pseudoPOD
ppodt_array_i <fred_c, int> name[name_array_len];
private: int name_value[name_array_len]; public:
// place in constructor() of class fred_c
for (int i=0; i<name_array_len; ++i) {
name[i].ep = this;
name[i].ep_get = &fred_c::get_name;
name[i].ep_set = &fred_c::set_name;
name[i].index_value = i;
}
// the get_name(int index) &
// set_name(int index, int in) functions
// are identical to those used for
// pseudoPODs made by macros.
Arrays of Other Non-Pointer pseudoPODs Using Templates:
same as for integer, but for "int" substitute one of "unsigned int", "unsigned long", "short", "unsigned short", "char", "unsigned char", "bool", "float", "double" or "long double".
In addition, for "float", "double", & "long double" change the template name from ppodt_array_i to ppodt_array_f.
Arrays of Integer Pointer pseudoPODs Using Templates:
const static int name_array_len = 39; // create
// the pseudoPOD
ppodt_array_p <fred_c, int*> name[name_array_len];
private: int *name_value[name_array_len]; public:
// place in constructor() of enclosing class
for (int i=0; i<name_array_len; ++i) {
name[i].ep = this;
name[i].ep_get = &fred_c::get_name;
name[i].ep_set = &fred_c::set_name;
name[i].index_value = i;
}
// the *get_name(int index) &
// *set_name(int index, int *in)
// functions are identical to
// those used for pseudoPODs made by macros.
Arrays of Other Pointer pseudoPODs Using Templates:
same as for integer, but for "int*" or "int *" substitute one of "unsigned int*", "unsigned long*", "short*", "unsigned short*", "char*", "unsigned char*", "bool*", "float*", "double*" or "long double*".
Read Only or Write Only pseudoPODs Using Templates:
same as before, but add "_ro" or "_wo" to the ppodt_i() call, so that:
ppodt_i() |
becomes |
ppodt_i_ro() or ppodt_i_wo(), |
ppodt_p() |
becomes |
ppodt_p_ro() or ppodt_p_wo(), |
ppodt_array() |
becomes |
ppodt_array_ro() or ppodt_array_wo(), and |
ppodt_array_p() |
becomes |
ppodt_array_p_ro() or ppodt_array_p_wo() |